﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cofe.Core;
using Cofe.Core.Filter;
using Cofe.Core.Implements;
using Cofe.Core.Utils;

namespace Cofe.Web
{
    public static class EntrySerializerHelpers
    {
        public static FindUsingParseName FindUsingParseName = new FindUsingParseName();
        public static FindUsingId FindUsingId = new FindUsingId();
        public static UpdateToCache UpdateToCache = new UpdateToCache();
    }

    public class FindUsingParseName : EntrySerializerHelperBase
    {
        public override CofeSystemInfo FindFunc(ParameterDic parameters)
        {
            if (parameters.ContainsKey("parseName") && parameters["parseName"] is string)
                return EntryFE.ParsePathAsync(parameters["parseName"] as string).Result as CofeSystemInfo;
            return null;
        }
    }

    public class FindSpecifyingId : EntrySerializerHelperBase
    {
        public FindSpecifyingId(Guid id)
        {
            _id = id;
        }

        private Guid _id;

        public override CofeSystemInfo FindFunc(ParameterDic parameters)
        {
            return EntryFE.ParsePathAsync(_id.ToString(), ParsableType.Guid, EntryConstructionFlags.Default).Result as CofeSystemInfo;
        }
    }


    public class FindUsingId : EntrySerializerHelperBase
    {
        public override CofeSystemInfo FindFunc(ParameterDic parameters)
        {
            if (parameters.ContainsKey("id") && (parameters["id"] is string || parameters["id"] is Guid))
            {
                Guid id = (parameters["id"] is Guid) ? (Guid)parameters["id"] : new Guid(parameters["id"] as string);
                return EntryFE.ParsePathAsync(id.ToString(), ParsableType.Guid, EntryConstructionFlags.Default).Result as CofeSystemInfo;
            }
            return null;
        }
    }

    public class FindUsingLookupName : EntrySerializerHelperBase
    {
        public FindUsingLookupName(ICofeDirectoryInfo relativeDir)
        {
            _relativeDir = relativeDir;
        }

        private ICofeDirectoryInfo _relativeDir;

        public override CofeSystemInfo FindFunc(ParameterDic parameters)
        {
            if (parameters.ContainsKey("name") && (parameters["name"] is string))
            {
                string name = (string)parameters["name"];
                return _relativeDir.EnumerateCofeSystemInfos(FilterCollections.FromName(name)).FirstOrDefault() as CofeSystemInfo;
            }
            return null;
        }
    }

    public class CreateUsingNameAndType : EntrySerializerHelperBase
    {
        public CreateUsingNameAndType(ICofeDirectoryInfo relativeDir)
        {
            _relativeDir = relativeDir;
        }

        private ICofeDirectoryInfo _relativeDir;

        public override CofeSystemInfo FindFunc(ParameterDic parameters)
        {
            if (parameters.ContainsKey("name") && (parameters["name"] is string) && parameters.ContainsKey("type") && (parameters["type"] is string))
            {
                string name = (string)parameters["name"];
                string type = (string)parameters["type"];
                var retVal = AsyncUtils.RunSync(() => _relativeDir.CreateAsync(type, name)) as CofeSystemInfo;

                string entryPath = retVal.ParseName;

                if (retVal.Id == Guid.Empty)
                    for (int i = 0; i < 10; i++)
                    {
                        Task.Delay(1000).Wait();
                        retVal = AsyncUtils.RunSync(() => EntryFE.TryParsePathAsync<ICofeSystemInfo>(entryPath, ParsableType.ParsePathLookup)) as CofeSystemInfo;
                        if (retVal.Id != Guid.Empty)
                            break;
                    }
                if (retVal.Id == Guid.Empty)
                    return null;

                return retVal;
            }
            return null;
        }
    }

    public class UpdateToCache : EntrySerializerHelperBase
    {
        public override void UpdateFunc(CofeSystemInfo entry, ParameterDic parameters)
        {
            foreach (var pp in parameters)
            {
                switch (pp.Key)
                {
                    case "parseName":
                    case "id":
                        break;
                    default:
                        var prop = CofeServices.PropertyDictionary.GetProperty(pp.Key);
                        if (prop != null)
                        {

                            if (entry.Properties.Behaviors.IsPropertySupported(prop))
                            {
                                var type = CofeServices.PropertyDictionary.AttributeHelper.GetDefaultType(prop);
                                var value = pp.Value;
                                entry.Properties.Behaviors.SetPropertyPair(PropertyPair.FromValue(prop, value),
                                    PropertyRetrivalOptions.CacheOnly);
                            }
                        }
                        break;
                }
            }
        }
    }

}
